﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;
using CNKI.TPI.Web.Base;
using CNKI.TPI.Web.Sys.IBLL;
using CNKI.TPI.Web.Sys.IDAO;
using CNKI.TPI.Web.Sys.Model;

namespace CNKI.TPI.Web.Sys.BLL
{
    public enum SecurityType
    {
        Null = 0,
        Above = 1,
        Spec = 2,
    };
    class UserService : BaseService, IUserService
    {
        private IUserDAO userDao = null;

        public UserService(IUserDAO userDao)
        {
            this.userDao = this.generator.CreateInterfaceProxyWithTarget<IUserDAO>(userDao, new IInterceptor[] { new LogInterceptor() });
        }

        /// <summary>
        /// 验证用户
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public LoginUserInfo ValidateUser(string userName, string password, bool needPWD = true)
        {
            LoginUserInfo result = null;
            try {
                password = null == password ? "" : password;
                SYS_CMS_USER userinfo = userDao.GetUser(userName);
                if (null != userinfo && (password.Equals(userinfo.Password) || !needPWD))
                {
                    IList<SYS_CMS_USER_IP> userIPList = userDao.GetUserIP(userinfo.SysID);
                    bool isInIPRange = false;
                    foreach(SYS_CMS_USER_IP item in userIPList)
                    {
                        isInIPRange = IPUntil.IsInIPRange(item.SIP, item.EIP, IPUntil.GetIP());
                        if (isInIPRange)
                        {
                            break;
                        }
                    }
                    if (isInIPRange)
                    {
                        result = new LoginUserInfo();
                        result.UserID = userinfo.SysID;
                        result.UserCode = userinfo.Username;
                        result.UserName = userinfo.RealName;
                        result.password = userinfo.Password;
                        //初始化角色权限
                        ProcessRole(result);
                        //初始化数据权限
                        ProcessDBRight(result);
                        //初始化密级
                        ProcessSecurity(result, userinfo);
                    }
                }
            }
            catch(Exception ex){
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userInfo"></param>
        private void ProcessRole(LoginUserInfo userInfo)
        {
            IList<SYS_CMS_USER_GROUP> userGroup = userDao.GetUserGroup(userInfo.UserID);
            userInfo.Role = userDao.GetGroup(userGroup.Select(c => c.GroupID));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userInfo"></param>
        private void ProcessDBRight(LoginUserInfo userInfo)
        {
            IList<SYS_CMS_USER_ACL_DB_RIGHT> dbRightList = userDao.GetUserDBRight(userInfo.UserID);
            UserDBInfo dbInfo;
            foreach (SYS_CMS_USER_ACL_DB_RIGHT item in dbRightList)
            {
                dbInfo = new UserDBInfo();
                dbInfo.DBID = item.DBID;
                dbInfo.DownloadPerDay = item.DownloadCountOfDay;
                dbInfo.TotalDownload = item.MaxDownloadCount;
                dbInfo.Field = item.RightFieldName.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList<string>();
                dbInfo.OperateFunc = item.RightValue;
                dbInfo.Navi = item.RightClsValue;
                userInfo.DBInfo.Add(dbInfo);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userInfo"></param>
        private void ProcessSecurity(LoginUserInfo userInfo, SYS_CMS_USER user)
        {
            IList<SYS_CMS_SECURITY> dbRightList = userDao.GetSecurityInfo();
            switch ((SecurityType)user.SecurityType)
            {
                case SecurityType.Null:
                    userInfo.Security = new List<string>();
                    userInfo.Security.Add("0");
                    break;
                case SecurityType.Above:
                    userInfo.Security = dbRightList.Where(c => (int.Parse(c.Value) <= int.Parse(user.SecurityValue))).Select(c => c.Value).ToList<string>();
                    break;
                case SecurityType.Spec:
                    userInfo.Security = user.SecurityValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList<string>();
                    break;
            }
        }

        public DataTable GetAllUser()
        {
            return userDao.GetAllUser();
        }
    }
}
